home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / hdrline.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  12KB  |  548 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "mutt_curses.h"
  21.  
  22. #ifdef _PGPPATH
  23. #include "pgp.h"
  24. #endif
  25.  
  26. #include <ctype.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <locale.h>
  30.  
  31. int mutt_is_mail_list (ADDRESS *addr)
  32. {
  33.   LIST *p;
  34.  
  35.   if (!addr->mailbox)
  36.     return 0;
  37.   for (p = MailLists; p; p = p->next)
  38.     if (strncasecmp (addr->mailbox, p->data, strlen (p->data)) == 0)
  39.       return 1;
  40.   return 0;
  41. }
  42.  
  43. static int
  44. check_for_mailing_list (ADDRESS *adr, char *pfx, char *buf, int buflen)
  45. {
  46.   ADDRESS *list;
  47.   int len = strlen (pfx);
  48.  
  49.   for (; adr; adr = adr->next)
  50.   {
  51.     if (mutt_is_mail_list (adr))
  52.     {
  53.       strfcpy (buf, pfx, buflen);
  54.       len = strlen (pfx);
  55.       buflen -= len;
  56.       buf += len;
  57.  
  58.       if (option (OPTREVALIAS) && (list = alias_reverse_lookup (adr)) && list->personal)
  59.     strfcpy (buf, list->personal, buflen);
  60.       else
  61.     strfcpy (buf, adr->mailbox, buflen);
  62.       return 1;
  63.     }
  64.   }
  65.   return 0;
  66. }
  67.  
  68. static void print_addr (char *pfx, char *s, size_t l, ADDRESS *a)
  69. {
  70.   ADDRESS *t;
  71.  
  72.   if (pfx)
  73.   {
  74.     strfcpy (s, pfx, l);
  75.     while (*s)
  76.     {
  77.       s++;
  78.       l--;
  79.     }
  80.   }
  81.  
  82.   if (option (OPTREVALIAS) && (t = alias_reverse_lookup (a)) && t->personal)
  83.     strfcpy (s, t->personal, l);
  84.   else if (a->personal)
  85.     strfcpy (s, a->personal, l);
  86.   else
  87.   {
  88.     t = a->next;
  89.     a->next = NULL;
  90.     rfc822_write_address (s, l, a);
  91.     a->next = t;
  92.   }
  93. }
  94.  
  95. static void make_from (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
  96. {
  97.   int me;
  98.  
  99.   me = mutt_addr_is_user (hdr->from);
  100.  
  101.   if (do_lists || me)
  102.   {
  103.     if (check_for_mailing_list (hdr->to, "To ", buf, len))
  104.       return;
  105.     if (check_for_mailing_list (hdr->cc, "Cc ", buf, len))
  106.       return;
  107.   }
  108.  
  109.   *buf = 0;
  110.   if (me && hdr->to)
  111.     print_addr ("To ", buf, len, hdr->to);
  112.   else if (me && hdr->cc)
  113.     print_addr ("Cc ", buf, len, hdr->cc);
  114.   else if (hdr->from)
  115.     print_addr (NULL, buf, len, hdr->from);
  116. }
  117.  
  118. int mutt_user_is_recipient (ADDRESS *a)
  119. {
  120.   for (; a; a = a->next)
  121.     if (mutt_addr_is_user (a))
  122.       return 1;
  123.   return 0;
  124. }
  125.  
  126. /* Return values:
  127.  * 0: user is not in list
  128.  * 1: user is unique recipient
  129.  * 2: user is in the TO list
  130.  * 3: user is in the CC list
  131.  * 4: user is originator
  132.  */
  133. static int user_is_recipient (ENVELOPE *hdr)
  134. {
  135.   if (mutt_addr_is_user (hdr->from))
  136.     return 4;
  137.  
  138.   if (mutt_user_is_recipient (hdr->to))
  139.   {
  140.     if (hdr->to->next || hdr->cc)
  141.       return 2; /* non-unique recipient */
  142.     else
  143.       return 1; /* unique recipient */
  144.   }
  145.  
  146.   if (mutt_user_is_recipient (hdr->cc))
  147.     return 3;
  148.  
  149.   return (0);
  150. }
  151.  
  152. /*
  153.  * %a = address of author
  154.  * %c = size of message in bytes
  155.  * %C = current message number
  156.  * %d = date and time of message (using strftime)
  157.  * %f = entire from line
  158.  * %F = entire from line, unless from self
  159.  * %i = message-id
  160.  * %l = number of lines in the message
  161.  * %L = list-from function.
  162.  * %m = number of messages in the mailbox
  163.  * %n = name of author
  164.  * %s = subject
  165.  * %S = short message status (e.g., N/O/D/!/r/-)
  166.  * %t = `to:' field (recipients)
  167.  * %T = $to_chars
  168.  * %u = user (login) name of author
  169.  * %Z = status flags
  170.  *
  171.  * %>X = right justify rest of line and pad with character X
  172.  * %|X = pad to end of line with character X
  173.  *
  174.  */
  175.  
  176. void
  177. _mutt_make_string (char *dest, size_t destlen, char *s, HEADER *hdr, int flags)
  178. {
  179.   char buf[STRING], buf2[STRING], prefix[SHORT_STRING], fmt[SHORT_STRING];
  180.   char *cp;
  181.   int len, count;
  182.   char *wptr = dest; /* pointer to current writing position */
  183.   int wlen = 0;      /* how many characters written so far */
  184.   int ch;            /* char to use as filler */
  185.   int do_locales;
  186.  
  187.   destlen--; /* save room for the terminal null (\0) character */
  188.   dest[destlen] = 0;
  189.   while (*s && wlen < destlen)
  190.   {
  191.     if (*s == '%')
  192.     {
  193.       s++;
  194.       if (*s == '%')
  195.       {
  196.     *wptr++ = '%';
  197.     wlen++;
  198.     s++;
  199.     continue;
  200.       }
  201.       /* strip off the formatting commands */
  202.       cp = prefix;
  203.       count = 0;
  204.       while (count < sizeof (prefix) && (*s == '-' || *s == '.' || isdigit (*s)))
  205.       {
  206.     *cp++ = *s++;
  207.         count++;
  208.       }
  209.       *cp = 0;
  210.  
  211.       switch (*s)
  212.       {
  213.     case '>': /* right justify the rest of the line */
  214.  
  215.       s++;
  216.       ch = *s++;
  217.       _mutt_make_string (buf, sizeof (buf), s, hdr, flags);
  218.       len = (COLS < destlen ? COLS : destlen) - wlen - strlen (buf);
  219.       while (len > 0 && wlen < destlen)
  220.       {
  221.         *wptr++ = ch;
  222.         len--;
  223.         wlen++;
  224.       }
  225.       /* skip over the rest of the string */
  226.       s += strlen (s);
  227.       break;
  228.  
  229.     case '|': /* pad to end of line */
  230.  
  231.       s++;
  232.       ch = *s++;
  233.       if (destlen > COLS)
  234.         destlen = COLS;
  235.       for (; wlen < destlen; wlen++)
  236.         *wptr++ = ch;
  237.       break;
  238.  
  239.     case 'a':
  240.  
  241.       mutt_simple_address (buf2, sizeof (buf2), hdr->env->from);
  242.       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
  243.       snprintf (buf, sizeof (buf), fmt, buf2);
  244.       break;
  245.  
  246.     case 'c':
  247.  
  248.       mutt_pretty_size (buf2, sizeof (buf2), (long) hdr->content->length);
  249.       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
  250.       snprintf (buf, sizeof (buf), fmt, buf2);
  251.       break;
  252.  
  253.     case 'C':
  254.  
  255.       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
  256.       snprintf (buf, sizeof (buf), fmt, hdr->msgno + 1);
  257.       break;
  258.  
  259.     case 'd':
  260.     case '{':
  261.     case '[':
  262.  
  263.       /* preprocess $date_format to handle %Z */
  264.       {
  265.         char *p = buf;
  266.  
  267.         cp = (*s == 'd') ? DateFmt : (s + 1);
  268.         if (*cp == '!')
  269.         {
  270.           do_locales = 0;
  271.           cp++;
  272.         }
  273.         else
  274.           do_locales = 1;
  275.  
  276.         len = sizeof (buf) - 1;
  277.         while (len > 0 && ((*s == 'd' && *cp) ||
  278.                   (*s == '{' && *cp != '}') || 
  279.                   (*s == '[' && *cp != ']')))
  280.         {
  281.           if (*cp == '%')
  282.           {
  283.         cp++;
  284.         if (*cp == 'Z' && *s != '[')
  285.         {
  286.           if (len >= 5)
  287.           {
  288.             sprintf (p, "%c%02d%02d", hdr->zoccident ? '-' : '+',
  289.                  hdr->zhours, hdr->zminutes);
  290.             p += 5;
  291.             len -= 5;
  292.           }
  293.           else
  294.             break; /* not enough space left */
  295.         }
  296.         else
  297.         {
  298.           if (len >= 2)
  299.           {
  300.             *p++ = '%';
  301.             *p++ = *cp;
  302.             len -= 2;
  303.           }
  304.           else
  305.             break; /* not enough space */
  306.         }
  307.         cp++;
  308.           }
  309.           else
  310.           {
  311.         *p++ = *cp++;
  312.         len--;
  313.           }
  314.         }
  315.         *p = 0;
  316.       }
  317.  
  318.       if (do_locales)
  319.         setlocale (LC_TIME, Locale);
  320.  
  321.       {
  322.         struct tm *tm; 
  323.  
  324.         if (*s == '[')
  325.           tm = localtime (&hdr->date_sent);
  326.         else
  327.         {
  328.           time_t T;
  329.  
  330.           /* restore sender's time zone */
  331.           T = hdr->date_sent;
  332.           if (hdr->zoccident)
  333.         T -= (hdr->zhours * 3600 + hdr->zminutes * 60);
  334.           else
  335.         T += (hdr->zhours * 3600 + hdr->zminutes * 60);
  336.           tm = gmtime (&T);
  337.         }
  338.         
  339.         strftime (buf2, sizeof (buf2), buf, tm);
  340.       }
  341.  
  342.       if (do_locales)
  343.         setlocale (LC_TIME, "C");
  344.  
  345.       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
  346.       snprintf (buf, sizeof (buf), fmt, buf2);
  347.       if (len > 0 && *s != 'd')
  348.         s = cp;
  349.       break;
  350.  
  351.     case 'f':
  352.  
  353.       buf2[0] = 0;
  354.       rfc822_write_address (buf2, sizeof (buf2), hdr->env->from);
  355.       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
  356.       snprintf (buf, sizeof (buf), fmt, buf2);
  357.       break;
  358.  
  359.     case 'F':
  360.  
  361.       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
  362.       make_from (hdr->env, buf2, sizeof (buf2), 0);
  363.       snprintf (buf, sizeof (buf), fmt, buf2);
  364.       break;
  365.  
  366.     case 'i':
  367.  
  368.       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
  369.       snprintf (buf, sizeof (buf), fmt, hdr->env->message_id ? hdr->env->message_id : "<no.id>");
  370.       break;
  371.  
  372.     case 'l':
  373.  
  374.       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
  375.       snprintf (buf, sizeof (buf), fmt, (int) hdr->lines);
  376.       break;
  377.  
  378.     case 'L':
  379.  
  380.       make_from (hdr->env, buf